package Principal;

// <editor-fold defaultstate="collapsed" desc="imports">
import Comprobaciones.ComprobarEstanciaCampus;
import Utilidades.Celda;
import Utilidades.Errores;
import Utilidades.VideoWall;
import controlador.*;
import controlador.AccesoControlador;
import controlador.ParkingControlador;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import modelo.entidades.*;
import modelo.*;
import vista.Alerta.AlertaVista;
import vista.ListaInteres.ListaInteresVista;
import vista.Login;
import vista.Parking.PanelAvisoParkingVistaImp;
import vista.Parking.PanelBarreraParkingVistaImp;
import vista.Parking.PanelInfoAccesoVistaImp;
import vista.Parking.PanelInfoParkingVistaImp;
import vista.Parking.ParkingVista;
import vista.RegistroAcceso.RegistroAccesoVista;
import vista.RegistroAcceso.RegistroAccesoVistaImp;
import vista.RegistroParking.RegistroParkingVista;
import vista.RegistroParking.RegistroParkingVistaImp;
import vista.VentanaGeneral;
// </editor-fold>

public class Main {

    static AccesoModelo accesoModelo;
    static AccesoControlador accesoControlador;
    static ComprobarEstanciaCampus comprobando;
    static RegistroAccesoModelo registroAccesoModelo;
    static RegistroAccesoControlador registroAccesoControlador;
    static ParkingModelo parkingModelo;
    static ParkingControlador parkingControlador;
    static RegistroParkingModelo registroParkingModelo;
    static RegistroParkingControlador registroParkingControlador;
    static AlertaModelo alertaModelo;
    static AlertaControlador alertaControlador;
    static VehiculoModelo vehiculoModelo;
    static VehiculoControlador vehiculoControlador;
    static UsuarioModelo usuarioModelo;
    static UsuarioControlador usuarioControlador;
    static ListaInteresModelo listaInteresModelo;
    static ListaInteresControlador listaInteresControlador;

    public static void main(String[] args) {
        VideoWall videoWall = new VideoWall((new VentanaGeneral(new RegistroParkingVistaImp(null, new PanelInfoParkingVistaImp(null), new PanelBarreraParkingVistaImp(null), new PanelAvisoParkingVistaImp(null), null))).getSize());
        accesoModelo = new AccesoModeloImp();
        accesoControlador = new AccesoControladorImp();
        comprobando = new ComprobarEstanciaCampus();
        registroAccesoModelo = new RegistroAccesoModeloImp();
        registroAccesoControlador = new RegistroAccesoControladorImp();
        parkingModelo = new ParkingModeloImp();
        parkingControlador = new ParkingControladorImp();
        registroParkingModelo = new RegistroParkingModeloImp();
        registroParkingControlador = new RegistroParkingControladorImp();
        alertaModelo = new AlertaModeloImp();
        alertaControlador = new AlertaControladorImp();
        vehiculoModelo = new VehiculoModeloImp();
        vehiculoControlador = new VehiculoControladorImp();
        usuarioModelo = new UsuarioModeloImp();
        usuarioControlador = new UsuarioControladorImp();
        listaInteresModelo = new ListaInteresModeloImp();
        listaInteresControlador = new ListaInteresControladorImp();

        //actualizarPlazasVacantes();
        generarVentanasAcceso(videoWall);
        generarVentanasParking(videoWall);
        setupAlertas();
        setupListasInteres();
        actualizarPlazasVacantes();

        ComprobarEstanciaCampus comprobar = new ComprobarEstanciaCampus();
        Thread hilo = new Thread(comprobar);
        hilo.start();

        java.awt.EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new Login().setVisible(true);
            }
        });
    }

    // <editor-fold defaultstate="collapsed" desc="Métodos">
    public static void generarVentanasAcceso(VideoWall vw) {
        Celda celda = null;

        List<RegistroAccesoVista> registrosAccesosVistas = new ArrayList<RegistroAccesoVista>();
        List<ParkingVista> parkingVistas = new ArrayList<ParkingVista>();
        try {
            List<Acceso> accesos = getAccesoModelo().listar();
            for (Acceso a : accesos) {
                ParkingVista pi = new PanelInfoAccesoVistaImp(a);
                RegistroAccesoVista registroAccesoVista = new RegistroAccesoVistaImp(a, pi);
                registrosAccesosVistas.add(registroAccesoVista);
                parkingVistas.add(pi);
                final VentanaGeneral ventana = new VentanaGeneral(registroAccesoVista);
                celda = vw.obtenerCelda();
                if (celda != null) {
                    ventana.setLocation(celda.getCoordenadas());
                }
                ventana.setTitle(a.getNombre());
                java.awt.EventQueue.invokeLater(new Runnable() {

                    @Override
                    public void run() {
                        ventana.display();
                    }
                });

            }
            getRegistroAccesoControlador().setup(getRegistroAccesoModelo(), registrosAccesosVistas);
            getParkingControlador().setup(getParkingModelo(), parkingVistas);
        } catch (SQLException e) {
            Errores.mostrarError(e);
        } catch (Exception e) {
            Errores.mostrarError(e);
        }
    }

    public static void generarVentanasParking(VideoWall vw) {
        Celda celda = null;
        List<RegistroParkingVista> registrosParkingsVistas = new ArrayList<RegistroParkingVista>();
        List<ParkingVista> parkingVistas = new ArrayList<ParkingVista>();
        try {
            List<Parking> parkings = getParkingModelo().listar();
            for (Parking p : parkings) {
                ParkingVista pi = new PanelInfoParkingVistaImp(p);
                ParkingVista pb = new PanelBarreraParkingVistaImp(p);
                ParkingVista pa = new PanelAvisoParkingVistaImp(p);
                RegistroParkingVista registroParkingVista = new RegistroParkingVistaImp(p, pi, pb, pa, vehiculoModelo);
                registrosParkingsVistas.add(registroParkingVista);
                parkingVistas.add(pi);
                parkingVistas.add(pb);
                parkingVistas.add(pa);
                VentanaGeneral ventana = new VentanaGeneral(registroParkingVista);
                celda = vw.obtenerCelda();
                if (celda != null) {
                    ventana.setLocation(celda.getCoordenadas());
                }
                ventana.setTitle(p.getNombre());
                ventana.display();
            }
            getRegistroParkingControlador().setup(getRegistroParkingModelo(), registrosParkingsVistas);
            getParkingControlador().setup(getParkingModelo(), parkingVistas);
        } catch (SQLException e) {
            Errores.mostrarError(e);
        } catch (Exception e) {
            Errores.mostrarError(e);
        }
    }

    public static void actualizarPlazasVacantes() {
        java.awt.EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                try {
                    /* Como actualizarPlazasVacantes se ejecuta antes que generarVentanaParking, es
                     * necesario establecer el setup del controlador para relacionar el modelo, aunque
                     * en el siguiente método se defina la lista de ventanas*/
                    getParkingControlador().setup(getParkingModelo(), new ArrayList<ParkingVista>());
                    List<Parking> parkings = getParkingModelo().listar();
                    for (Parking parking : parkings) {
                        int ocupadas = getRegistroParkingModelo().ocupadas(parking.getNombre());
                        parking.setPlazasLibres(parking.getPlazas() - ocupadas);
                        getParkingModelo().actualizarEntidad(parking);
                    }
                } catch (SQLException ex) {
                    Errores.mostrarError(ex);
                } catch (Exception ex) {
                    Errores.mostrarError(ex);
                }
            }
        });



    }

    public static void setupAlertas() {
        List<AlertaVista> alertasVistas = new ArrayList<AlertaVista>();
        alertaControlador.setup(getAlertaModelo(), alertasVistas);
    }

    public static void setupListasInteres() {
        List<ListaInteresVista> listasInteres = new ArrayList<ListaInteresVista>();
        listaInteresControlador.setup(getListaInteresModelo(), listasInteres);
    }
    //</editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Getters">
    public static AccesoControlador getAccesoControlador() {
        return accesoControlador;
    }

    public static AccesoModelo getAccesoModelo() {
        return accesoModelo;
    }

    public static AlertaControlador getAlertaControlador() {
        return alertaControlador;
    }

    public static AlertaModelo getAlertaModelo() {
        return alertaModelo;
    }

    public static ListaInteresControlador getListaInteresControlador() {
        return listaInteresControlador;
    }

    public static ListaInteresModelo getListaInteresModelo() {
        return listaInteresModelo;
    }

    public static ParkingControlador getParkingControlador() {
        return parkingControlador;
    }

    public static ParkingModelo getParkingModelo() {
        return parkingModelo;
    }

    public static RegistroAccesoControlador getRegistroAccesoControlador() {
        return registroAccesoControlador;
    }

    public static RegistroAccesoModelo getRegistroAccesoModelo() {
        return registroAccesoModelo;
    }

    public static RegistroParkingControlador getRegistroParkingControlador() {
        return registroParkingControlador;
    }

    public static RegistroParkingModelo getRegistroParkingModelo() {
        return registroParkingModelo;
    }

    public static UsuarioControlador getUsuarioControlador() {
        return usuarioControlador;
    }

    public static UsuarioModelo getUsuarioModelo() {
        return usuarioModelo;
    }

    public static VehiculoControlador getVehiculoControlador() {
        return vehiculoControlador;
    }

    public static VehiculoModelo getVehiculoModelo() {
        return vehiculoModelo;
    }

    public static ComprobarEstanciaCampus getComprobando() {
        return comprobando;
    }
    //</editor-fold>
}
